package utils.group
{
    import com.adobe.crypto.MD5;
    
    import flash.events.*;
    
    import utils.ArrayIterator;
    import utils.IClear;
    import utils.IIterator;

    public class SelectGroup extends EventDispatcher implements IClear
    {
        public static const SINGLE_SELECT:int = 1;
        public static const MULTI_SELECT:int = 2;
        
        private var _currentType:int = 1;
        private var _groupName:String;
        private var _callbackLock:Boolean = false;
        private var _itemList:Array;
        private var _currentIndex:int = -1;


        public function get currentType() : int
        {
            return _currentType;
        }
        public function set currentType(value:int):void
        {
            if (value != SINGLE_SELECT && value != MULTI_SELECT)
            {
                value = SINGLE_SELECT;
            }
            _currentType = value;
        }
        public function get length():int
        {
            return _itemList.length;
        }
        public function get allItems():Array
        {
            return _itemList;
        }
        public function get currentItem():ISelectGroupItem
        {
            if (_currentType != SINGLE_SELECT || _currentIndex < 0)
            {
                return null;
            }
            return _itemList[_currentIndex];
        }
        public function get currentIndex():int
        {
            return ((_currentIndex != SINGLE_SELECT) ? -1 : _currentIndex);
        }
        public function set currentIndex(value:int):void
        {
            _currentIndex = value;
        }
        public function get currentItems():Array
        {
            var item:ISelectGroupItem = null;
            var items:Array = [];
            for each (item in _itemList)
            {
                if (item.selected)
                {
                    items.push(item);
                }
            }
            return items;
        }

        public function SelectGroup(type:int = SelectGroup.SINGLE_SELECT)
        {
            _currentType = type;
            _groupName = MD5.hash(Math.random().toString() + Math.random().toString() + Math.random().toString() + Math.random().toString() + Math.random().toString());
            _itemList = [];
            return;
        }
        private function selectedCallback(item:ISelectGroupItem):void
        {
            if (!item.selected) return;
            var data:* = item.groupName.split(_groupName)[1];
            if (data == null) return;
            if (_currentType == SINGLE_SELECT)
            {
                _currentIndex = int(data);
                for(var i:int = 0; i < _itemList.length; i++) {
                    _itemList[i].selected = (i == _currentIndex);
                }
            } else if (_currentType == MULTI_SELECT) {
            	
            }
            if (!_callbackLock)
            {
                dispatchEvent(new Event(Event.CHANGE));
            }
            return;
        }
        private function getNextIdleIndex():int
        {
        	var index:int;
            for(index = 0; index < _itemList.length; index++) {
                if (_itemList[index] == null) break;
            }
            return index;
        }

        public function getItemIndex(item:ISelectGroupItem):int
        {
            if (!contains(item)) return -1;
            var index:int = int(item.groupName.split(_groupName)[1]);
            return index;
        }

        public function selectFirstSelectable():void
        {
            if (currentType != SelectGroup.SINGLE_SELECT) return;
            reset();
            _callbackLock = true;
            var iterator:IIterator = createIterator();
            while (iterator.hasNext)
            {
                var item:ISelectGroupItem = iterator.next() as ISelectGroupItem;
                if (item.selectable)
                {
                    item.selected = true;
                    break;
                }
            }
            _callbackLock = false;
        }
        public function clear():void
        {
            while (_itemList.length > 0)
            {
                var item:ISelectGroupItem = _itemList[0] as ISelectGroupItem;
                if (item == null)
                {
                    _itemList.splice(0, 1);
                    continue;
                }
                item.selectedCallback = null;
                item.groupName = "";
                _itemList.splice(0, 1);
            }
            reset();
        }
        public function reset():void
        {
            for each (var item:ISelectGroupItem in _itemList)
            {
                item.selected = false;
            }
            _currentIndex = -1;
        }
        public function createIterator():IIterator
        {
            return new ArrayIterator(_itemList);
        }
        public function addItem(item:ISelectGroupItem):void
        {
            var index:int = getNextIdleIndex();
            item.selected = false;
            item.groupName = _groupName + index;
            item.selectedCallback = selectedCallback;
            _itemList[index] = item;
        }
        public function getItemAt(index:int):ISelectGroupItem
        {
            return _itemList[index];
        }
        public function contains(item:ISelectGroupItem):Boolean
        {
            var obj:Object = item.groupName.split(_groupName)[1];
            return (obj != null);
        }
        public function removeItem(item:ISelectGroupItem):void
        {
            var index:int = getItemIndex(item);
            if (index < 0) return;
            if (index == _currentIndex)
            {
                _currentIndex = -1;
            }
            item.selectedCallback = null;
            item.groupName = "";
            _itemList.splice(index, 1);
        }
    }
}